package com.fafi.spring.aop.selfadvice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;

import java.util.Arrays;

/**
 * 1、横切关注点
 * 对哪些方法进行拦截，拦截后怎么处理，这些关注点称之为横切关注点
 *
 * 切面（aspect）
 * 类是对物体特征的抽象，切面就是对横切关注点的抽象
 *
 * 连接点（joinpoint）
 * 被拦截到的点，因为Spring只支持方法类型的连接点，
 * 所以在Spring中连接点指的就是被拦截到的方法，
 * 实际上连接点还可以是字段或者构造器
 *
 * 切入点（pointcut）
 * 对连接点进行拦截的定义
 *
 *通知（advice）
 * 所谓通知指的就是指拦截到连接点之后要执行的代码，
 * 通知分为前置、后置、异常、最终、环绕通知五类
 *
 * 目标对象
 * 代理的目标对象
 *
 * 7、织入（weave）
 * 将切面应用到目标对象并导致代理对象创建的过程
 *
 * 8、引入（introduction）
 * 在不修改代码的前提下，引入可以在运行期为类动态地添加一些方法或字段
 */
@Aspect
public class LogAspects {
	@Pointcut("execution(int com.fafi.spring.aop.service.impl.MathService.div(int,int))")
	public void pointCut() { System.out.println("===pointcut===="); }

	@Before("com.fafi.spring.aop.selfadvice.LogAspects.pointCut()")
	public void logStart(JoinPoint joinPoint) {
		System.out.println(joinPoint.getSignature().getName() + " 除法运行,参数是：" + Arrays.asList(joinPoint.getArgs()));
	}

	@After("com.fafi.spring.aop.selfadvice.LogAspects.pointCut()")
	public void logEnd() {
		System.out.println("除法结束");
	}


	@AfterReturning(value = "com.fafi.spring.aop.selfadvice.LogAspects.pointCut())", returning = "result")
	public void logReturn2(JoinPoint joinPoint, Object result) {
		System.out.println(joinPoint.getSignature().getName() + "除法返回:" + result);
	}

	@AfterThrowing(value = "com.fafi.spring.aop.selfadvice.LogAspects.pointCut()", throwing = "exception")
	public void logException(Exception exception) {
		System.out.println("除法异常");
	}
}
